home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / graphics / gnuplot / hrcgraph.asm < prev    next >
Assembly Source File  |  1993-05-11  |  8KB  |  359 lines

  1. TITLE    Hercules graphics module
  2.  
  3. ;    Michael Gordon - 8-Dec-86
  4. ;
  5. ; Certain routines were taken from the Hercules BIOS of    Dave Tutelman - 8/86
  6. ; Others came from pcgraph.asm included in GNUPLOT by Colin Kelley
  7. ;
  8. ; modified slightly by Colin Kelley - 22-Dec-86
  9. ;    added header.mac, parameterized declarations
  10. ; added dgroup: in HVmodem to reach HCh_Parms and HGr_Parms - 30-Jan-87
  11. ; modified by Russell Lang 3 Jun 1988
  12. ;    added H_init
  13.  
  14. include header.mac
  15.  
  16. if1
  17. include lineproc.mac
  18. endif
  19.  
  20.  
  21. GPg1_Base equ 0B800h    ; Graphics page 1 base address
  22.  
  23. _text    segment
  24.  
  25.     public _H_line, _H_color, _H_mask, _HVmode, _H_puts
  26.     public _H_init
  27.  
  28. HCfg_Switch equ    03BFH    ; Configuration Switch - software switch 
  29.             ; to select graphics card memory map
  30.  
  31. beginproc _H_init
  32.     mov al, 03H    ; allow graphics in b8000:bffff
  33.     mov dx, HCfg_Switch
  34.     out dx, al
  35.     ret
  36. _H_init endp
  37.  
  38. hpixel    proc near
  39.     ror word ptr bmask,1
  40.     jc cont
  41.     ret
  42. cont:
  43.     push ax
  44.     push bx
  45.     push cx
  46.     push dx
  47.     push si
  48.     mov cx,ax        ; x
  49.     mov dx,bx        ; y
  50. ;
  51. ; [couldn't this be done faster with a lookup table? -cdk]
  52. ;
  53.     ; first compute the address of byte to be modified
  54.     ; = 90*[row/4] + [col/8] + 2^D*[row/4] + 2^F*page
  55.     mov    bh,cl        ; col (low order) in BH
  56.     mov    bl,dl        ; row (low order) in BL
  57.     and    bx,0703H    ; mask the col & row remainders
  58. IFDEF iAPX286
  59.     shr    cx,3        ; col / 8
  60.     shr    dx,2        ; row / 4
  61.     mov    al,90
  62.     mul    dx        ; AX = 90*[ row/4 ]
  63.     add    ax,cx        ;  ... + col/8
  64.     shl    bl,5        ; align row remainder
  65. ELSE            ; same as above, obscure but fast for 8086
  66.     shr    cx,1        ; divide col by 8
  67.     shr    cx,1
  68.     shr    cx,1
  69.     shr    dx,1        ; divide row by 4
  70.     shr    dx,1
  71.     shl    dx,1        ; begin fast multiply by 90 (1011010 B)
  72.     mov    ax,dx
  73.     shl    dx,1
  74.     shl    dx,1
  75.     add    ax,dx
  76.     shl    dx,1
  77.     add    ax,dx
  78.     shl    dx,1
  79.     shl    dx,1
  80.     add    ax,dx        ; end fast multiply by 90
  81.     add    ax,cx        ; add on the col/8
  82.     shl    bl,1        ; align row remainder
  83.     shl    bl,1
  84.     shl    bl,1
  85.     shl    bl,1
  86.     shl    bl,1
  87. ENDIF
  88.     add    ah,bl        ; use aligned row remainder
  89. end_adr_calc:            ; address of byte is now in AX
  90.     mov    dx,GPg1_Base    ; base of pixel display to DX
  91.     mov    es,dx        ; ...and thence to segment reg
  92.     mov    si,ax        ; address of byte w/ pixel to index reg
  93.     mov    cl,bh        ; bit addr in byte
  94.     mov    al,80H        ; '1000 0000' in AL 
  95.     shr    al,cl        ; shift mask to line up with bit to read/write
  96. set_pix:            ; set the pixel
  97.     or    es:[si],al    ; or the mask with the right byte
  98.     pop si
  99.     pop dx
  100.     pop cx
  101.     pop bx
  102.     pop ax
  103.     ret
  104. hpixel endp
  105.  
  106. lineproc _H_line, hpixel
  107.  
  108. ;
  109. ; clear - clear page 1 of the screen buffer to zero (effectively, blank
  110. ;    the screen)
  111. ;
  112. clear   proc near
  113.     push es
  114.     push ax
  115.     push cx
  116.     push di
  117.     mov ax, GPg1_Base
  118.     mov es, ax
  119.     xor di, di
  120.     mov cx, 4000h
  121.     xor ax, ax
  122.     cld
  123.     rep stosw            ; zero out screen page
  124.     pop di
  125.     pop cx
  126.     pop ax
  127.     pop es
  128.     ret
  129. clear    endp
  130.  
  131. beginproc _H_color
  132.     push bp
  133.     mov bp,sp
  134.     mov al,[bp+X]            ; color
  135.     mov byte ptr color,al
  136.     pop bp
  137.     ret
  138. _H_color endp
  139.  
  140. beginproc _H_mask
  141.     push bp
  142.     mov bp,sp
  143.     mov ax,[bp+X]            ; mask
  144.     mov word ptr bmask,ax
  145.     pop bp
  146.     ret
  147. _H_mask endp
  148.  
  149. HCtrl_Port    equ    03B8H    ; Hercules 6845 control port IO addr
  150. HIndx_Port    equ    03B4H    ; Hercules 6845 index port IO addr
  151. HScrn_Enable    equ    008h    ; Control port bit to enable video
  152. HCh_Mode    equ    020h    ; Character output mode
  153. HGr_Mode    equ    082h    ; Graphics output mode page 1
  154.  
  155. parm_count equ 12
  156.  
  157. beginproc _HVmode
  158.     push bp
  159.     mov bp, sp
  160.     push si
  161.     mov ax, [bp+X]
  162.     or ah, al
  163.     mov al, HCh_Mode        ; Assume character mode is wanted
  164.     mov si, offset dgroup:HCh_Parms
  165.     cmp ah, 0            ; nonzero means switch to graphics
  166.     jz vmode_ok
  167.     call near ptr clear        ; clear the graphics page
  168.     mov al, HGr_Mode
  169.     mov si, offset dgroup:HGr_Parms
  170. vmode_ok:
  171.     mov dx, HCtrl_Port
  172.     out dx, al            ; Set Hercules board to proper mode
  173.     call near ptr setParms        ; Set the 6845 parameters
  174.     or al, HScrn_Enable        ; Enable the video output
  175.     out dx, al
  176.     pop si
  177.     pop bp
  178.     ret
  179. _HVmode    endp
  180.  
  181. setParms proc near        ; Send 6845 parms to Hercules board
  182.     push ax
  183.     push dx
  184.     push si            
  185.     mov dx, HIndx_Port    ; Index port addr -> DX
  186.     mov ah, 0        ; 0 -> parameter counter
  187. sp_loop:
  188.     mov al, ah
  189.     out dx, al        ; output to 6845 addr register
  190.     inc dx            ; next output to data register
  191.     mov al, [si]        ; next control byte -> al
  192.     inc si
  193.     out dx, al        ; output control byte
  194.     dec dx            ; 6845 index addr -> dx
  195.     inc ah            ; bump addr
  196.     cmp ah, parm_count
  197.     jnz sp_loop
  198.     pop si
  199.     pop dx
  200.     pop ax
  201.     ret
  202. setParms endp
  203.  
  204. ; H_puts - print text in graphics mode
  205. ;
  206. ;    cx = row
  207. ;    bx = column
  208. ;    si = address of string (null terminated) to print
  209.  
  210. beginproc _H_puts
  211.     push bp
  212.     mov bp, sp
  213.     push si
  214.     push ds
  215.     mov si, [bp+X]            ; string offset
  216.  
  217. ifdef LARGE_DATA
  218.     mov ds, [bp+X+2]        ; string segment
  219.     mov cx, [bp+X+4]        ; row
  220.     mov bx, [bp+X+6]        ; col
  221. else
  222.     mov cx, [bp+X+2]        ; row
  223.     mov bx, [bp+X+4]        ; col
  224. endif
  225.  
  226. ploop:    lodsb                ; get next char
  227.     or    al, al            ; end of display?
  228.     je    pdone
  229.     call near ptr display
  230.     inc    bx            ; bump to next column
  231.     jmp    ploop
  232. pdone:    pop ds
  233.     pop si
  234.     pop bp
  235.     ret
  236. _H_puts    endp
  237.  
  238. ;
  239. ; display - output an 8x8 character from the IBM ROM to the Herc board
  240. ;
  241. ; AX = char, BX = column (0-89), CX = row(0-42)  ** all preserved **
  242. ;
  243. CON8    db    8
  244. CON180    db    180
  245. IBMROM    equ    0F000h
  246. CHARTAB    equ    0FA6Eh
  247.  
  248. display    proc near
  249.     push    ds            ; save the lot
  250.     push    es
  251.     push    ax
  252.     push    bx
  253.     push    cx
  254.     push    dx
  255.     push    si
  256.     push    di
  257.  
  258. ; setup ds -> IBM ROM, and si -> index into IBM ROM character table located
  259. ;    at 0fa6eh in the ROM
  260.  
  261.     and    ax, 07fh
  262.     mul    cs:CON8            ; mult by 8 bytes of table per char
  263.     mov    si, ax
  264.     mov    ax, IBMROM
  265.     mov    ds, ax
  266.     assume    ds:nothing
  267.     add    si, CHARTAB        ; add offset of character table
  268.  
  269. ; compute index into Hercules screen memory for scan line 0.  The remaining
  270. ;    seven scan lines are all at fixed offsets from the first.
  271. ;
  272. ;    Since graphics mode treats the screen as sets of 16x4 "characters",
  273. ;    we need to map an 8x8 real character onto the front or back of
  274. ;    a pair of graphics "characters".  The first four scan lines of our
  275. ;    8x8 character will map to the top graphics "character", and the second
  276. ;    four scan lines map to the graphics character on the "line" (4 scan
  277. ;    lines high) below it.
  278. ;
  279. ;    For some exotic hardware reason (probably speed), all scan line 0
  280. ;    bits (i.e. every fourth scan line) are stored in memory locations
  281. ;    0-2000h in the screen buffer.  All scan line 1 bits are stored
  282. ;    2000h-4000h.  Within these banks, they are stored by rows.  The first
  283. ;    scan line on the screen (scan line 0 of graphics character row 0)
  284. ;    is the first 45 words of memory in the screen buffer.  The next 45
  285. ;    words are the first scan line graphics row 1, and since graphics
  286. ;    "characters" are 4 bits high, this second scan line is physically
  287. ;    the fifth scan line displayed on the screen.
  288. ;
  289. ;    SO, to display an 8x8 character, the 1st and 5th rows of dots are
  290. ;    both scan line 0 of the graphics "character", the 2nd and 6th are
  291. ;    scan line 1, and so on.
  292. ;
  293. ;    The column (0-89) tells which byte in a scan line we need to load.
  294. ;    Since it takes two rows of graphics characters to hold one row of
  295. ;    our characters, column+90 is a index to scan line 4 rows of pixels
  296. ;    higher (n+4).  Thus 180 bytes of screen memory in any bank (0h, 2000h,
  297. ;    4000h, 6000h) represent a row of 8x8 characters.
  298. ;    
  299. ;    The starting location in screen memory for the first scan line of
  300. ;    a character to be displayed will be:      (row*180)+column
  301. ;    The 5th scan line will be at:        (row*180)+column+90
  302. ;
  303. ;    The second and 6th scan lines will be at the above offsets plus
  304. ;    the bank offset of 2000h.  The third and 7th, add 4000h and finally
  305. ;    the 4th and 8th, add 6000h.
  306. ;
  307.     mov    ax, GPg1_Base
  308.     mov    es, ax            ; es = hercules page 0
  309.     mov    ax, cx            ; get row
  310.     mul    cs:CON180        ; mult by 180(10)
  311.     mov    di, ax            ; di = index reg
  312.     cld                ; insure right direction
  313.  
  314. ;output 8 segments of character to video ram
  315.  
  316.     lodsb                ; line 0
  317.     mov    es:[di+bx], al
  318.     lodsb
  319.     mov    es:[di+bx+2000h], al    ; line 1
  320.     lodsb
  321.     mov    es:[di+bx+4000h], al    ; line 2
  322.     lodsb
  323.     mov    es:[di+bx+6000h], al    ; line 3
  324.     lodsb
  325.     mov    es:[di+bx+90], al    ; line 4
  326.     lodsb
  327.     mov    es:[di+bx+2000h+90], al    ; line 5
  328.     lodsb
  329.     mov    es:[di+bx+4000h+90], al    ; line 6
  330.     lodsb
  331.     mov    es:[di+bx+6000h+90], al    ; line 7
  332.  
  333.     pop    di
  334.     pop    si
  335.     pop    dx
  336.     pop    cx
  337.     pop    bx
  338.     pop    ax
  339.     pop    es
  340.     pop    ds
  341.     ret
  342. display    endp
  343.  
  344. _text    ends
  345.  
  346. _data    segment
  347. bmask    dw -1
  348. color    db 1
  349. _data    ends
  350.  
  351. const    segment
  352. HCh_Parms db     61H, 50H, 52H, 0FH, 19H, 06H, 19H, 19H, 02H, 0DH, 0BH, 0CH
  353. HGr_Parms db    35H, 2DH, 2EH, 07H, 5BH, 02H, 57H, 57H, 02H, 03H, 00H, 00H
  354. const    ends
  355.  
  356.     end
  357.  
  358.  
  359.